import os
import sys
import rtconfig

print("开始构建...")

if os.getenv('RTT_ROOT'):
    RTT_ROOT = os.getenv('RTT_ROOT')
else:
    RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../..')
    print('RTT_ROOT: ' + RTT_ROOT)

# FMT path
FMU_ROOT = os.path.normpath(os.getcwd() + '/../../../../../..')
FMU_ROOT = os.path.join(FMU_ROOT, 'fmt')
print('FMU_ROOT: ' + FMU_ROOT)

fmt_tools = os.path.join(os.getcwd(), 'fmt_tools')
sys.path.append(fmt_tools)
print('FMT tools path: ' + fmt_tools)

sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
    from building import *
except:
    print('Cannot found RT-Thread root directory, please check RTT_ROOT')
    print(RTT_ROOT)
    exit(-1)

# ===== Set the target =====
TARGET = 'build/fmt_' + rtconfig.BOARD + '.' + rtconfig.TARGET_EXT
print('Target = ' + TARGET)

print("----------------------------------------")

# ===== Add option to SCons =====
AddOption('--vehicle',
                dest = 'vehicle',
                type = 'string',
                default = 'Multicopter',
                help = 'Specify the vehicle type')

AddOption('--airframe', 
                dest='airframe', 
                type='int', 
                nargs=1, 
                default = 1, 
                action='store',
                help='Specify the airframe value')

'''
    创建一个 Environment 对象，指定要使用的工具为 'mingw'
    'mingw' 是一个用于 Windows 的 GCC 编译器集合
    设置汇编器\编译器\链接器\静态库打包工具(archiver)等, 以及对应的参数
    使用 env 来构建目标文件、库或可执行文件
'''
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
    AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
    CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
    AR = rtconfig.AR, ARFLAGS = '-rc',
    CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
    LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS, LIBS = rtconfig.LLIBS)

# set VEHICLE_TYPE macro for low-level usage
env.Append(CPPDEFINES = [('VEHICLE_TYPE', GetOption('vehicle'))])
env.Append(CPPDEFINES = [('AIRFRAME', GetOption('airframe'))])

# Add sys execute PATH to env PATH
env.PrependENVPath('PATH', os.getenv('PATH'))
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)

if rtconfig.PLATFORM in ['iccarm']:
    env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
    env.Replace(ARFLAGS = [''])
    env.Replace(LINKCOM = env["LINKCOM"] + ' --map rtthread.map')

# 设置或导出系统中的环境变量，使其在子进程sconscript中也可用.
Export('RTT_ROOT')
Export('rtconfig')

SDK_ROOT = os.path.abspath('./')
SCONS_ROOT = os.path.abspath('./')

if os.path.exists(SDK_ROOT + '/libraries'):
    libraries_path_prefix = SDK_ROOT + '/libraries'
else:
    libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'

SDK_LIB = libraries_path_prefix

Export('SDK_LIB')
Export('SCONS_ROOT')

# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)

qx_library = 'libs'
rtconfig.BSP_LIBRARY_TYPE = qx_library

# include libraries
objs.extend(SConscript(os.path.join(libraries_path_prefix, qx_library, 'SConscript')))

# include drivers
objs.extend(SConscript(os.path.join(libraries_path_prefix, 'drivers', 'SConscript')))

# (Dir('#'): 返回当前SConscript文件的目录,将这个Dir对象转换成一个字符串。
# 通常，这个字符串会是目录的绝对路径
# 遍历目录列表并构建每个目录中的 SConscript 文件
cwd = str(Dir('#'))
list = os.listdir(FMU_ROOT)
vdir = 'build/fmt'
for d in list:
    path = os.path.join(FMU_ROOT, d)
    print(path)
    if os.path.isfile(os.path.join(path, 'SConscript')):
        print(os.path.join(path, 'SConscript'))
        objs.extend(SConscript(os.path.join(path, 'SConscript'),
                    variant_dir=vdir + '/' + d, duplicate=0))

def postbuild(target, source, env):
    print('\n----- postbuild step 1: generate SRAM images')
    cmd = rtconfig.TOOLCHAIN_PATH + 'bin/gen_ram_image.exe --coretype core0 --inputexec fmt_' + rtconfig.BOARD + '.out --toolbinpath ' + rtconfig.TOOLCHAIN_PATH + 'bin'
    os.chdir('build')
    os.system(cmd)
    os.chdir('..')
    
    print('\n----- postbuild step 2: generate FLASH images')
    cmd = 'cp bootloader/*.dat build/'
    os.system(cmd)
    
    cmd = 'python ' + rtconfig.WORKING_DIR + '/gen_flash_image.py --compact-hex --dual-boot --dcsm'
    os.chdir('build')
    os.system(cmd)
    os.chdir('..')

# make a building
print('------------------------------------------------------')
print('Building...')
DoBuilding(TARGET, objs)
env.AddPostAction(TARGET, postbuild)


# Copy debug files to Core0 directory
import os
import re
import shutil
from pathlib import Path

def find_project_name(file_path):
    """从 .project 文件中提取 <name> 标签内容"""
    #print(f"正在读取文件: {file_path}")
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
            
        # 使用正则表达式搜索 <name> 标签内容
        match = re.search(r'<name>\s*(.*?)\s*</name>', content)
        if match:
            return match.group(1)
        return None
    except Exception as e:
        print(f"读取文件失败: {e}")
        return None

def get_parent_path(path, levels=1):
    for _ in range(levels):
        path = os.path.dirname(path)
    return path

#print('Copying build files to Core0 directory...')
def CopyBuildToRelease(target, source, env):
    CURRENT_PATH = os.path.dirname(os.getcwd())
    RPOJECT_ROOT = get_parent_path(CURRENT_PATH, 7) # 返回当前目录的上7级目录
    #print(f"RPOJECT_ROOT: {RPOJECT_ROOT}")

    project_file = Path(RPOJECT_ROOT) / r".project"
    if not project_file.exists():
        print(f"文件不存在: {project_file}")

    # 提取项目名称
    project_name = find_project_name(project_file)
    project_name += '_core0'

    if project_name:
        print(f"项目名称: {project_name}")
    else:
        print("未找到 <name> 标签内容")

    bulid_files = [
        f'fmt_{rtconfig.BOARD}.out',
        # f'fmt_{rtconfig.BOARD}.map',
        # f'fmt_{rtconfig.BOARD}.dis',
        # f'fmt_{rtconfig.BOARD}.S.dis'
    ]

    release_files = [
        f'{project_name}.out',
        # f'{project_name}.map',
        # f'{project_name}.dis',
        # f'{project_name}.S.dis'
    ]

    ldscript_files = [
        'ldscript_Memory.ld',
    ]

    Build_path = os.getcwd() + r"\build"
    Build_path = Build_path.replace("\\", "/") 
    #print(f"Build_path: {Build_path}")

    Release_path = get_parent_path(CURRENT_PATH, 6) + r"\Release"
    Release_path = Release_path.replace("\\", "/") 
    #print(f"Release_path: {Release_path}")

    ldscript_path = get_parent_path(CURRENT_PATH, 7) + r"\libs\ldscript"
    ldscript_path = ldscript_path.replace("\\", "/") 
    #print(f"ldscript_path: {ldscript_path}")

    for file in release_files:
        if os.path.exists(Release_path + '/' + file):
            os.remove(Release_path + '/' + file)

    for file in ldscript_files:
        if os.path.exists(ldscript_path + '/' + file):
            os.remove(ldscript_path + '/' + file)

    for file in ldscript_files:
        ld_path = os.path.join(ldscript_path, file)
        shutil.copy2(file, ld_path)
        print(f'  {file} -> {ld_path}')

    for src, dest in zip(bulid_files, release_files):
        src_path  = os.path.join(Build_path,   src)
        dest_path = os.path.join(Release_path, dest)
        
        if os.path.exists(src_path):
            shutil.copy2(src_path, dest_path) # 复制文件并保留源文件的元数据
            print(f'  {src_path} -> {dest_path}')
        else:
            print(f'  Warning: {src_path} not found!')

env.AddPostAction(TARGET, CopyBuildToRelease)

